/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package classe.controlador;

import classe.controlador.exceptions.IllegalOrphanException;
import classe.controlador.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import classe.entidade.Setor;
import classe.entidade.Movimento;
import java.util.ArrayList;
import java.util.List;
import classe.entidade.RequisicaoMaterial;
import classe.entidade.Usuario;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author Kellison
 */
public class UsuarioJpaController implements Serializable {

    public UsuarioJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    
    public UsuarioJpaController() {
        this.emf = Persistence.createEntityManagerFactory("GerenciadorAlmoxarifadoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Usuario usuario) {
        if (usuario.getMovimentoList() == null) {
            usuario.setMovimentoList(new ArrayList<Movimento>());
        }
        if (usuario.getRequisicaoMaterialList() == null) {
            usuario.setRequisicaoMaterialList(new ArrayList<RequisicaoMaterial>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Setor idTblSetor = usuario.getIdTblSetor();
            if (idTblSetor != null) {
                idTblSetor = em.getReference(idTblSetor.getClass(), idTblSetor.getId());
                usuario.setIdTblSetor(idTblSetor);
            }
            List<Movimento> attachedMovimentoList = new ArrayList<Movimento>();
            for (Movimento movimentoListMovimentoToAttach : usuario.getMovimentoList()) {
                movimentoListMovimentoToAttach = em.getReference(movimentoListMovimentoToAttach.getClass(), movimentoListMovimentoToAttach.getId());
                attachedMovimentoList.add(movimentoListMovimentoToAttach);
            }
            usuario.setMovimentoList(attachedMovimentoList);
            List<RequisicaoMaterial> attachedRequisicaoMaterialList = new ArrayList<RequisicaoMaterial>();
            for (RequisicaoMaterial requisicaoMaterialListRequisicaoMaterialToAttach : usuario.getRequisicaoMaterialList()) {
                requisicaoMaterialListRequisicaoMaterialToAttach = em.getReference(requisicaoMaterialListRequisicaoMaterialToAttach.getClass(), requisicaoMaterialListRequisicaoMaterialToAttach.getId());
                attachedRequisicaoMaterialList.add(requisicaoMaterialListRequisicaoMaterialToAttach);
            }
            usuario.setRequisicaoMaterialList(attachedRequisicaoMaterialList);
            em.persist(usuario);
            if (idTblSetor != null) {
                idTblSetor.getUsuarioList().add(usuario);
                idTblSetor = em.merge(idTblSetor);
            }
            for (Movimento movimentoListMovimento : usuario.getMovimentoList()) {
                Usuario oldIdTblUsuarioOfMovimentoListMovimento = movimentoListMovimento.getIdTblUsuario();
                movimentoListMovimento.setIdTblUsuario(usuario);
                movimentoListMovimento = em.merge(movimentoListMovimento);
                if (oldIdTblUsuarioOfMovimentoListMovimento != null) {
                    oldIdTblUsuarioOfMovimentoListMovimento.getMovimentoList().remove(movimentoListMovimento);
                    oldIdTblUsuarioOfMovimentoListMovimento = em.merge(oldIdTblUsuarioOfMovimentoListMovimento);
                }
            }
            for (RequisicaoMaterial requisicaoMaterialListRequisicaoMaterial : usuario.getRequisicaoMaterialList()) {
                Usuario oldIdTblUsuarioOfRequisicaoMaterialListRequisicaoMaterial = requisicaoMaterialListRequisicaoMaterial.getIdTblUsuario();
                requisicaoMaterialListRequisicaoMaterial.setIdTblUsuario(usuario);
                requisicaoMaterialListRequisicaoMaterial = em.merge(requisicaoMaterialListRequisicaoMaterial);
                if (oldIdTblUsuarioOfRequisicaoMaterialListRequisicaoMaterial != null) {
                    oldIdTblUsuarioOfRequisicaoMaterialListRequisicaoMaterial.getRequisicaoMaterialList().remove(requisicaoMaterialListRequisicaoMaterial);
                    oldIdTblUsuarioOfRequisicaoMaterialListRequisicaoMaterial = em.merge(oldIdTblUsuarioOfRequisicaoMaterialListRequisicaoMaterial);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Usuario usuario) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario persistentUsuario = em.find(Usuario.class, usuario.getId());
            Setor idTblSetorOld = persistentUsuario.getIdTblSetor();
            Setor idTblSetorNew = usuario.getIdTblSetor();
            List<Movimento> movimentoListOld = persistentUsuario.getMovimentoList();
            List<Movimento> movimentoListNew = usuario.getMovimentoList();
            List<RequisicaoMaterial> requisicaoMaterialListOld = persistentUsuario.getRequisicaoMaterialList();
            List<RequisicaoMaterial> requisicaoMaterialListNew = usuario.getRequisicaoMaterialList();
            List<String> illegalOrphanMessages = null;
            for (Movimento movimentoListOldMovimento : movimentoListOld) {
                if (!movimentoListNew.contains(movimentoListOldMovimento)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Movimento " + movimentoListOldMovimento + " since its idTblUsuario field is not nullable.");
                }
            }
            for (RequisicaoMaterial requisicaoMaterialListOldRequisicaoMaterial : requisicaoMaterialListOld) {
                if (!requisicaoMaterialListNew.contains(requisicaoMaterialListOldRequisicaoMaterial)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain RequisicaoMaterial " + requisicaoMaterialListOldRequisicaoMaterial + " since its idTblUsuario field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (idTblSetorNew != null) {
                idTblSetorNew = em.getReference(idTblSetorNew.getClass(), idTblSetorNew.getId());
                usuario.setIdTblSetor(idTblSetorNew);
            }
            List<Movimento> attachedMovimentoListNew = new ArrayList<Movimento>();
            for (Movimento movimentoListNewMovimentoToAttach : movimentoListNew) {
                movimentoListNewMovimentoToAttach = em.getReference(movimentoListNewMovimentoToAttach.getClass(), movimentoListNewMovimentoToAttach.getId());
                attachedMovimentoListNew.add(movimentoListNewMovimentoToAttach);
            }
            movimentoListNew = attachedMovimentoListNew;
            usuario.setMovimentoList(movimentoListNew);
            List<RequisicaoMaterial> attachedRequisicaoMaterialListNew = new ArrayList<RequisicaoMaterial>();
            for (RequisicaoMaterial requisicaoMaterialListNewRequisicaoMaterialToAttach : requisicaoMaterialListNew) {
                requisicaoMaterialListNewRequisicaoMaterialToAttach = em.getReference(requisicaoMaterialListNewRequisicaoMaterialToAttach.getClass(), requisicaoMaterialListNewRequisicaoMaterialToAttach.getId());
                attachedRequisicaoMaterialListNew.add(requisicaoMaterialListNewRequisicaoMaterialToAttach);
            }
            requisicaoMaterialListNew = attachedRequisicaoMaterialListNew;
            usuario.setRequisicaoMaterialList(requisicaoMaterialListNew);
            usuario = em.merge(usuario);
            if (idTblSetorOld != null && !idTblSetorOld.equals(idTblSetorNew)) {
                idTblSetorOld.getUsuarioList().remove(usuario);
                idTblSetorOld = em.merge(idTblSetorOld);
            }
            if (idTblSetorNew != null && !idTblSetorNew.equals(idTblSetorOld)) {
                idTblSetorNew.getUsuarioList().add(usuario);
                idTblSetorNew = em.merge(idTblSetorNew);
            }
            for (Movimento movimentoListNewMovimento : movimentoListNew) {
                if (!movimentoListOld.contains(movimentoListNewMovimento)) {
                    Usuario oldIdTblUsuarioOfMovimentoListNewMovimento = movimentoListNewMovimento.getIdTblUsuario();
                    movimentoListNewMovimento.setIdTblUsuario(usuario);
                    movimentoListNewMovimento = em.merge(movimentoListNewMovimento);
                    if (oldIdTblUsuarioOfMovimentoListNewMovimento != null && !oldIdTblUsuarioOfMovimentoListNewMovimento.equals(usuario)) {
                        oldIdTblUsuarioOfMovimentoListNewMovimento.getMovimentoList().remove(movimentoListNewMovimento);
                        oldIdTblUsuarioOfMovimentoListNewMovimento = em.merge(oldIdTblUsuarioOfMovimentoListNewMovimento);
                    }
                }
            }
            for (RequisicaoMaterial requisicaoMaterialListNewRequisicaoMaterial : requisicaoMaterialListNew) {
                if (!requisicaoMaterialListOld.contains(requisicaoMaterialListNewRequisicaoMaterial)) {
                    Usuario oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial = requisicaoMaterialListNewRequisicaoMaterial.getIdTblUsuario();
                    requisicaoMaterialListNewRequisicaoMaterial.setIdTblUsuario(usuario);
                    requisicaoMaterialListNewRequisicaoMaterial = em.merge(requisicaoMaterialListNewRequisicaoMaterial);
                    if (oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial != null && !oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial.equals(usuario)) {
                        oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial.getRequisicaoMaterialList().remove(requisicaoMaterialListNewRequisicaoMaterial);
                        oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial = em.merge(oldIdTblUsuarioOfRequisicaoMaterialListNewRequisicaoMaterial);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = usuario.getId();
                if (findUsuario(id) == null) {
                    throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario usuario;
            try {
                usuario = em.getReference(Usuario.class, id);
                usuario.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The usuario with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Movimento> movimentoListOrphanCheck = usuario.getMovimentoList();
            for (Movimento movimentoListOrphanCheckMovimento : movimentoListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the Movimento " + movimentoListOrphanCheckMovimento + " in its movimentoList field has a non-nullable idTblUsuario field.");
            }
            List<RequisicaoMaterial> requisicaoMaterialListOrphanCheck = usuario.getRequisicaoMaterialList();
            for (RequisicaoMaterial requisicaoMaterialListOrphanCheckRequisicaoMaterial : requisicaoMaterialListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Usuario (" + usuario + ") cannot be destroyed since the RequisicaoMaterial " + requisicaoMaterialListOrphanCheckRequisicaoMaterial + " in its requisicaoMaterialList field has a non-nullable idTblUsuario field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Setor idTblSetor = usuario.getIdTblSetor();
            if (idTblSetor != null) {
                idTblSetor.getUsuarioList().remove(usuario);
                idTblSetor = em.merge(idTblSetor);
            }
            em.remove(usuario);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Usuario> findUsuarioEntities() {
        return findUsuarioEntities(true, -1, -1);
    }

    public List<Usuario> findUsuarioEntities(int maxResults, int firstResult) {
        return findUsuarioEntities(false, maxResults, firstResult);
    }

    private List<Usuario> findUsuarioEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Usuario.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Usuario findUsuario(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Usuario.class, id);
        } finally {
            em.close();
        }
    }

    public int getUsuarioCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Usuario> rt = cq.from(Usuario.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
